
import logging
import rd

__version__ = '1.0'

WEBFINGER_TYPE = 'application/jrd+json'
LEGACY_WEBFINGER_TYPES = ['application/json']

UNOFFICIAL_ENDPOINTS = {
#    'facebook.com': 'facebook-webfinger.appspot.com',
#    'twitter.com': 'twitter-webfinger.appspot.com',
}

logger = logging.getLogger("webfinger")


class WebFingerException(Exception):
    pass

class WebFingerClient(object):

    def __init__(self, timeout=None, official=False):
        self.official = official
        self.timeout = timeout

    def _parse_host(self, resource):

        (scheme, host, path) = rd.parse_uri_components(resource)

        if host in UNOFFICIAL_ENDPOINTS and not self.official:
            unofficial_host = UNOFFICIAL_ENDPOINTS[host]
            logger.debug('host %s is not supported, using unofficial endpoint %s' % (host, unofficial_host))
            host = unofficial_host

        return host

    def finger(self, resource, host=None, rel=None):

        import requests

        if not host:
            host = self._parse_host(resource)

        url = "https://%s/.well-known/webfinger" % host

        headers = {
            'User-Agent': 'python-webfinger/%s' % __version__,
            'Accept': ', '.join(rd.JRD_TYPES + rd.XRD_TYPES),
        }

        params = {'resource': resource}
        if rel:
            params['rel'] = rel

        resp = requests.get(url, params=params, headers=headers, timeout=self.timeout, verify=True)
        logger.debug('fetching RD from %s' % resp.url)

        content_type = resp.headers.get('Content-Type', '').split(';', 1)[0].strip()
        logger.debug('response content type: %s' % content_type)

        if content_type not in (rd.JRD_TYPES + rd.XRD_TYPES):
            raise WebFingerException('Invalid response type from server')

        ''' Returns an RD object '''
        return rd.loads(resp.content.decode(resp.encoding if resp.encoding else 'utf-8'), content_type)


def finger(resource, rel=None):
    """ Convenience method for invoking WebFingerClient.
    """
    return WebFingerClient().finger(resource, rel=rel)


if __name__ == '__main__':

    import argparse

    parser = argparse.ArgumentParser(description="Simple webfinger client.")
    parser.add_argument("acct", metavar="URI", help="account URI")
    parser.add_argument("-d", "--debug", dest="debug", action="store_true", help="print debug logging output to console")
    parser.add_argument("-r", "--rel", metavar="REL", dest="rel", help="desired relation")

    args = parser.parse_args()

    if args.debug:
        logging.basicConfig(level=logging.DEBUG)

    wf = finger(args.acct, rel=args.rel)

    print("--- %s ---" % wf.subject)

    if args.rel:

        link = wf.find_link(args.rel)

        if link is None:
            print("*** Link not found for rel=%s" % args.rel)
        else:
            print("%s:\n\t%s" % (args.rel, link))

    else:

        for rel in rd.KNOWN_RELS:
            link = getattr(wf, rel)
            if link:
                print('{}\t{}'.format(rel, link.href if link.href else link.template))
